package de.popforge.audio 
{
	import __AS3__.vec.Vector;
	import de.popforge.audio.driver.AudioDriver;
	import de.popforge.audio.driver.IAudioProcessor;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.media.Sound;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;	

	/**
	 * Simple MP3 Loader for extracting purpose.
	 * 
	 * @author Andre Michelle
	 */
	public class MP3Extractor
		implements IAudioProcessor
	{
		private const sound: Sound = new Sound();
		
		private const target: ByteArray = new ByteArray();
		
		private var _ready: Boolean;
		
		public function MP3Extractor( url: String )
		{
			_ready = false;
			
			registerListener();
			
			sound.load( new URLRequest( url ) );
		}

		public function process( buffer: Vector.<Vector.<Number>> ): void
		{
			var le: Vector.<Number> = buffer[0];
			var ri: Vector.<Number> = buffer[1];
			
			var i: int;
			var n: int;
			
			if( _ready )
			{
				target.position = 0;
				
				i = 0;
				n = sound.extract( target, AudioDriver.SIZE );

				target.position = 0;
				
				for( ; i < n ; ++i )
				{
					le[i] = target.readFloat();
					ri[i] = target.readFloat();
				}

				if( n < AudioDriver.SIZE )
				{
					n = AudioDriver.SIZE;

					for( ; i < n ; ++i )
					{
						le[i] = 0.0;
						ri[i] = 0.0;
					}
					
					_ready = false;
				}
			}
			else
			{
				i = 0;
				n = AudioDriver.SIZE;

				for( ; i < n ; ++i )
				{
					le[i] = 0.0;
					ri[i] = 0.0;
				}
			}
		}

		private function loadComplete( event: Event ): void
		{
			unregisterListener();
			
			_ready = true;
		}
		
		private function loadError( event: IOErrorEvent ): void
		{
			unregisterListener();
			
			trace( event.text );
		}

		private function registerListener(): void
		{
			sound.addEventListener( Event.COMPLETE, loadComplete );
			sound.addEventListener( IOErrorEvent.IO_ERROR, loadError );
		}

		private function unregisterListener(): void
		{
			sound.removeEventListener( Event.COMPLETE, loadComplete );
			sound.removeEventListener( IOErrorEvent.IO_ERROR, loadError );
		}
	}
}
